package sdk

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/valyala/fasthttp"
)

type PostResult struct {
	Code    int    `json:"code"`    //200:成功 详见【状态码】
	Message string `json:"message"` //接口描述信息
	Data    []byte `json:"data"`    //请求json数据
}

type PostResultNew struct {
	Code    int         `json:"code"`    //200:成功 详见【状态码】
	Message string      `json:"message"` //接口描述信息
	Data    interface{} `json:"data"`    //请求json数据
}

type HttpResponse2Platform struct {
	// 返回code
	Code int `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
	// 返回消息
	Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
	// 请求uri
	Uri string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"`
	// 操作类型 request： api请求返回 push:推送消息
	Action string `protobuf:"bytes,4,opt,name=action,proto3" json:"action,omitempty"`
	// 返回内容
	Data string `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"`
	// 版本
	Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"`
	// 时间戳
	Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
}

//服务发现

//成功代码
const SuccessCode = 200

//最后此请求的代码
var lastCode int

//请求的地址 以后会丢到数据库里面去

var host = GetPlatformHost()

const (
	userAgent   = "go client"
	contentType = "application/json; charset=utf-8"
	timeOut     = time.Second * 2
)

func PPost(url string, body []byte, agentId int32, timeoutReq ...time.Duration) ([]byte, error) {
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer func() {
		fasthttp.ReleaseRequest(req)
		fasthttp.ReleaseResponse(resp)
	}()
	req.SetRequestURI(url)
	req.Header.SetContentType(contentType)
	req.Header.SetUserAgent(userAgent)
	req.Header.SetMethod(http.MethodPost)

	if agentId == 0 {
		//req.Header.Add("Agent", "0")
	} else {
		req.Header.Add("Agent", fmt.Sprintf("%v", agentId))
	}
	fmt.Printf("============================ http request: %v\n", req)
	req.SetBody(body)
	if len(timeoutReq) == 0 {
		timeoutReq = append(timeoutReq, timeOut)
	}

	client := &fasthttp.Client{
		MaxConnsPerHost: 1024,
		ReadTimeout:     timeOut,
		WriteTimeout:    timeOut,
	}

	if err := client.DoTimeout(req, resp, timeoutReq[0]); err != nil {
		return nil, errors.New(fmt.Sprintf("调用服务%s超时：%s", url, err.Error()))
	}

	if resp.StatusCode() != http.StatusOK {
		return nil, errors.New(fmt.Sprintf("调用服务%s失败:%s", url, http.StatusText(resp.StatusCode())))
	}
	buf := new(bytes.Buffer)
	buf.Write(resp.Body())
	return buf.Bytes(), nil
}

func GetPlatformHost() (host string) {
	if os.Getenv("PLATFORM_INTERFACE") != "" { // k8s
		host = os.Getenv("PLATFORM_INTERFACE")
	} else { // local
		host = "http://10.0.0.32:8080"
	}

	return
}

//设置host 方便测试
func SetHost(url string) {
	if strings.HasSuffix(url, "/") {
		url = url[0 : len(url)-1]
	}
	host = url
}

func Host() string {
	return host
}

//获取最后一次操作的错误码
func GetLastErrorCode() int {
	return lastCode
}

//平台SDK接口
func post(url string, val interface{}) (err error) {

	var resp *http.Response
	resp, err = http.Post(url, "application/json", nil)
	if err != nil {
		return err
	}

	result := &PostResult{}

	var b []byte
	b, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	err = json.Unmarshal(b, result)
	if err != nil {
		return errors.New(fmt.Sprintf("%v | %v", err, string(b)))
	}

	lastCode = result.Code

	if SuccessCode != result.Code {
		return errors.New(result.Message)
	}

	if val != nil {
		err = json.Unmarshal(result.Data, val)
		if err != nil {
			return
		}
	}

	return
}

//json方式发送数据
func postJson(url string, data interface{}, val interface{}) (err error) {

	jsonStr, _ := json.Marshal(data)
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	req.Header.Add("content-type", "application/json")
	req.Header.Add("Agent", "")
	if err != nil {
		return err
	}
	defer req.Body.Close()

	client := &http.Client{Timeout: 5 * time.Second}
	resp, error := client.Do(req)
	if error != nil {
		return error
	}
	defer resp.Body.Close()

	result := &PostResult{}

	var b []byte
	b, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	err = json.Unmarshal(b, result)
	if err != nil {
		return errors.New(fmt.Sprintf("%v | %v", err, string(b)))
	}
	lastCode = result.Code

	if SuccessCode != result.Code {
		return errors.New(result.Message)
	}

	if val != nil {
		err = json.Unmarshal(result.Data, val)
		if err != nil {
			return
		}
	}

	return
}

// new for platform
func postJsonNew(url string, data interface{}, val interface{}, agentId int32) (err error) {

	jsonStr, _ := json.Marshal(data)
	//req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	//req.Header.Add("content-type", "application/json")
	//if agentId == 0 {
	//	req.Header.Add("Agent", "0")
	//} else {
	//	req.Header.Add("Agent", fmt.Sprintf("%v", agentId))
	//}
	//if err != nil {
	//	return err
	//}
	//defer req.Body.Close()

	//
	//client := &http.Client{Timeout: 5 * time.Second}
	//fmt.Printf("============================ http request: %v\n", req)
	//resp, error := client.Do(req)
	//if error != nil {
	//	return error
	//}
	//defer resp.Body.Close()

	//fmt.Printf("============================ http request: %v\n", req)
	resp, err := PPost(url, jsonStr, agentId, timeOut)
	if err != nil {
		return err
	}

	result := &PostResultNew{}

	//var b []byte
	//b, err = ioutil.ReadAll(resp.Body)
	//if err != nil {
	//	return err
	//}

	//err = json.Unmarshal(b, result)
	err = json.Unmarshal(resp, result)
	if err != nil {
		return errors.New(fmt.Sprintf("%v | %v", err, string(resp)))
		//return errors.New(fmt.Sprintf("%v | %v", err, string(b)))
	}

	if SuccessCode != result.Code {
		return errors.New(fmt.Sprintf("code(%v): %v", result.Code, result))
	}

	rd, err := json.Marshal(result.Data)
	if err != nil {
		return
	}

	if val != nil {
		err = json.Unmarshal(rd, val)
		if err != nil {
			return
		}
	}

	return
}

func postJsonNewNoRV(url string, data interface{}, agentId int32) (err error) {

	jsonStr, _ := json.Marshal(data)
	//req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	//req.Header.Add("content-type", "application/json")
	//if agentId == 0 {
	//	req.Header.Add("Agent", "0")
	//} else {
	//	req.Header.Add("Agent", fmt.Sprintf("%v", agentId))
	//}
	//if err != nil {
	//	return err
	//}
	//defer req.Body.Close()
	//
	//
	//
	//client := &http.Client{Timeout: 5 * time.Second}
	//resp, error := client.Do(req)
	//if error != nil {
	//	return error
	//}
	//defer resp.Body.Close()

	//fmt.Printf("============================ http request: %v\n", jsonStr)

	//fmt.Printf("============================ http request: %v\n", req)
	resp, err := PPost(url, jsonStr, agentId, timeOut)
	if err != nil {
		return err
	}

	result := &PostResultNew{}

	//var b []byte
	//b, err = ioutil.ReadAll(resp.Body)
	//if err != nil {
	//	return err
	//}

	//err = json.Unmarshal(b, result)
	err = json.Unmarshal(resp, result)
	if err != nil {
		return errors.New(fmt.Sprintf("%v | %v", err, string(resp)))
		//return errors.New(fmt.Sprintf("%v | %v", err, string(b)))
	}

	if SuccessCode != result.Code {
		return errors.New(result.Message)
	}

	return
}

//根据token获取用户信息
func GetUserInfoByToken(token string, val interface{}) (err error) {

	command := &UserGetUserCommand{
		Token: token,
	}

	err = postJsonNew(host+"/user/getUser", command, val, 0)
	if err != nil {
		return
	}

	return
}

//根据userId获取用户信息  invoked in playerserver
func GetUserInfoByID(userId int64, val interface{}) (err error) {

	command := &UserGetUserCommand{
		UserId: userId,
	}
	fmt.Printf("========================= UserGetUserCommand userId: %v\n", command.UserId)

	// request to platform
	err = postJsonNew(host+"/user/getUser", command, val, 0)
	if err != nil {
		return
	}

	return
}

//获取账户余额 invoked in payserver
func GetUserBalance(userId int64, agentId int32) (balance int64, err error) {

	command := &AccountGetBalanceCommand{
		UserId: userId,
	}

	response := &AccountGetBalanceInfo{}

	err = postJsonNew(host+"/account/getBalance", command, response, agentId)
	if err != nil {
		return
	}

	balance = response.Balance

	return
}

//游戏下分接口（减少玩家余额）
/**
参数
字段	字段名	类型	必填	备注
userId	用户id	int64,string	是
agentId	业主编号	int	是
tradeNo	流水号	string	是	唯一流水号
matchId	局编号	string	是
gameId	游戏id	string	是	游戏分配的id
roomId	房间编号	string	是
amount	金额	int64,string	是

返回：
balance 用户余额
err 错误
*/
//func DownUserScore(userId int64, agentId int32, matchId, gameId, roomId string, amount int64) (err error) {
//
//	command := &GameDownScoreCommand{
//		UserId:  userId,
//		MatchId: matchId,
//		GameId:  gameId,
//		RoomId:  roomId,
//		Amount:  amount,
//	}
//
//	err = postJsonNewNoRV(host+"/game/downScore", command, agentId)
//	if err != nil {
//		return
//	}
//
//	return
//}

// invoked in gameapi
func DownUserScoreNew(userId int64, agentId int32, matchId, gameId, roomId string, amount int64) (err error) {

	command := &GameDownAndUpScoreCommand{
		UserId:  userId,
		MatchId: matchId,
		GameId:  gameId,
		RoomId:  roomId,
		Amount:  amount,
	}

	fmt.Printf("=================== DownUserScore: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))

	err = postJsonNewNoRV(host+"/game/downScore", command, agentId)
	if err != nil {
		return
	}

	return
}

//游戏上分接口（增加玩家余额）
/**
参数：
字段	字段名	类型	必填	备注
userId	用户id	int64	是
agentId	业主编号	int	是
tradeNo	流水号	string	是	唯一流水号
matchId	局编号	string	是
gameId	游戏id	string	是	游戏分配的id
roomId	房间编号	string	是
amount	金额	int64,string	是
// invoked in gameapi
返回：
balance 用户余额
err 错误
*/
func UpUserScore(userId int64, agentId int32, role int, tradeNo, matchId, gameId, roomId string, amount int64, scoreType, bussType int, profitAmount int64) (err error) {

	command := &GameDownScoreCommand{
		UserId:  userId,
		MatchId: matchId,
		GameId:  gameId,
		RoomId:  roomId,
		Amount:  amount,
	}

	fmt.Printf("=================== UpUserScore: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))

	err = postJsonNewNoRV(host+"/game/upScore", command, agentId)
	if err != nil {
		return
	}

	return
}

// invoked in gameapi
func UpUserScoreNew(userId int64, agentId int32, matchId, gameId, roomId string, amount int64) (err error) {

	command := &GameDownAndUpScoreCommand{
		UserId:  userId,
		MatchId: matchId,
		GameId:  gameId,
		RoomId:  roomId,
		Amount:  amount,
	}

	fmt.Printf("=================== UpUserScore 2: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))

	err = postJsonNewNoRV(host+"/game/upScore", command, agentId)
	if err != nil {
		return
	}

	return
}

//通知平台 游戏开始

/**
参数：
字段	字段名	类型	必填	备注
userId	用户id	int64,string	是
agentId	业主编号	int	是
gameId	游戏ID	string	是	游戏分配的id
matchId	局编号	string	是
roomId	房间号	string	否
tableId	桌子号	string	否
gameInfo	游戏信息	string	否	游戏扩展信息
invoked in playerserver
返回: 无
*/
func SetGameStart(userId int64, gameId string, agentId int32) (err error) {

	command := &GameSetStartCommandNew{
		UserId: userId,
		GameId: gameId,
	}
	fmt.Printf("=================== SetGameStart user id: %v, game id: %v | %v\n", command.UserId, command.GameId, time.Now().Format(time.RFC3339Nano))
	err = postJsonNewNoRV(host+"/game/userStart", command, agentId)
	if err != nil {
		return
	}

	return
}

/**
参数
字段	字段名	类型	必填	备注
userId	用户id	int64,string	是
gameId	游戏ID	string	是	游戏分配的id
matchId	局编号	string	是
userIds	用户id列表	int64,string	否	批量结束用户时使用
 invoked in playerserver
返回：
无
*/
func SetGameEnd(userId int64, gameId string, agentId int32) (err error) {
	command := &GameSetEndCommandNew{
		UserId: userId,
		GameId: gameId,
	}
	fmt.Printf("=================== SetGameEnd user id: %v, game id: %v | %v\n", command.UserId, command.GameId, time.Now().Format(time.RFC3339Nano))
	err = postJsonNewNoRV(host+"/game/userEnd", command, agentId)
	if err != nil {
		return
	}

	return
}

/**
批量结束游戏
参数：
字段	字段名	类型	必填	备注
userIds	用户id列表	int64,string	是
gameId	游戏ID	string	是	游戏分配的id
matchId	局编号	string	是

返回: 无

*/
//func BatchSetGameEnd(userIds, gameId, matchId string) (err error) {
//	v := url.Values{}
//	v.Add("matchId", matchId)
//	v.Add("gameId", gameId)
//	v.Add("userIds", userIds)
//	err = post(host+"/game/setEnds?"+v.Encode(), nil)
//	return
//}

/**
游戏战绩推送接口

字段	字段名	类型	必填	备注
userId	用户id	int64,string	是
agentId	业主编号	int	是
gameId	游戏ID	string	是	游戏分配的id
matchId	局编号	string	是
roomId	房间号	string	是
tableId	桌子号	string	是
chairId	椅子号	int	否
profitAmount	盈利金额	int64,string	是
endCards	结算牌	string	否	结算时手牌【英文半角，分割】
drawAmount	抽水金额	int64,string	是

返回参数
无

//*/
//func PublishGameResult(userId int64, agentId int, gameId, matchId, roomId, tableId string, chairId int, profitAmount int64,
//	endCards string, drawAmount int64) (err error) {
//	//v := url.Values{}
//	//v.Add("userId", fmt.Sprintf("%v", userId))
//	//v.Add("agentId", fmt.Sprintf("%v", agentId))
//	//v.Add("matchId", matchId)
//	//v.Add("gameId", gameId)
//	//v.Add("roomId", roomId)
//	//v.Add("chairId", strconv.Itoa(chairId))
//	//v.Add("profitAmount", fmt.Sprintf("%v", userId))
//	//v.Add("endCards", endCards)
//	//v.Add("drawAmount", fmt.Sprintf("%v", drawAmount))
//	//err = post(host+"/game/result?"+v.Encode(), nil)
//	//return
//
//	command:=&GameResultCommand{
//		UserId:userId,
//		AgentId:agentId,
//		GameId:gameId,
//		MatchId:matchId,
//		RoomId:roomId,
//		TableId:tableId,
//		ChairId:chairId,
//		ProfitAmount:profitAmount,
//		EndCards:endCards,
//		DrawAmount:drawAmount,
//	}
//
//	err = postJsonNew(host+"/game/result",command,nil)
//	if err != nil {
//		return
//	}
//
//	return
//}

/**
游戏日志推送接口

字段	字段名	类型	必填	备注
userId	用户id	int64,string	是
gameId	游戏ID	string	是	游戏分配的id
matchId	局编号	string	是
content	日志内容	string	是

返回：无
*/
func PublishGameLog(userId int64, gameId, matchId, content string, agentId int32) (err error) {
	rds := make([]*GameLogRecordInfo, 0)
	rd := &GameLogRecordInfo{
		UserId:  userId,
		Content: content,
	}
	rds = append(rds, rd)

	command := &GameCreateLogsCommand{
		GameId:  gameId,
		MatchId: matchId,
		Records: rds,
	}

	err = postJsonNewNoRV(host+"/game/createLogs", command, agentId)
	if err != nil {
		return
	}

	return
}

/**
获取跑马灯规则

字段	字段名	类型	必填	备注
gameId	游戏ID	string	是	游戏分配的id
agentId	业主编号	int	是
  invoked in roomserver
*/

func SearchMarqueeRules(gameId string, val interface{}) error {

	command := &GetMarqueeRulesCommand{
		GameId: gameId,
	}
	fmt.Printf("=================== SearchMarqueeRules: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err := postJsonNew(host+"/game/searchMarqueeRules", command, val, 0)
	if err != nil {
		return err
	}

	return nil
}

/**
创建跑马灯信息

字段	字段名	类型	必填	备注
gameId	游戏ID	string	是	游戏分配的id
agentId	业主编号	int	是
content	跑马灯内容	string	是
 invoked in roomserver
*/
func CreateMarquee(agentId int32, gameId, content string, userId, ruleId int64, val interface{}) (err error) {

	command := &MessageCreateMarqueeCommand{
		GameId:  gameId,
		AgentId: agentId,
		Content: content,
		UserId:  userId,
		RuleId:  ruleId,
	}
	fmt.Printf("=================== CreateMarquee: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err = postJsonNew(host+"/message/createMarquee", command, val, agentId)
	if err != nil {
		return
	}

	return
}

/**
创建码量

字段	字段名	类型	必填	备注
userId	用户id	int64	是
agentId	业主编号	int	是
gameId	游戏ID	string	是	游戏分配的id
amount	码量	int64	是
note	备注	string	否

返回参数
无
 invoked in gameapi
*/
func CreateChips(userId int64, agentId int32, gameId string, amount int64, note string, val interface{}) (err error) {
	//v := url.Values{}
	//v.Add("userId", fmt.Sprintf("%v", userId))
	//v.Add("agentId", fmt.Sprintf("%v", agentId))
	//v.Add("gameId", gameId)
	//v.Add("amount", fmt.Sprintf("%v", amount))
	//v.Add("note", note)
	//err = post(host+"/chips/create?"+v.Encode(), nil)
	//return

	command := &ChipsCreateCommand{
		UserId:  userId,
		AgentId: agentId,
		GameId:  gameId,
		Amount:  amount,
		Note:    note,
	}
	fmt.Printf("=================== CreateChips: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err = postJsonNew(host+"/chips/create", command, val, agentId)
	if err != nil {
		return
	}

	return
}

/**
批量创建码量
字段	字段名	类型	必填	备注
agentId	业主编号	int	是
gameId	游戏ID	string	是	游戏分配的id
records	以下是记录列表	[]object
-userId	用户id	int64,string	是
-amount	码量	int64	是
-note	备注	string	否

*/
//func BatchCreateChips(agentId int, gameId string, records []ChipsRecordInfo) (err error) {
//	//v := url.Values{}
//	//v.Add("userId", fmt.Sprintf("%v", userId))
//	//v.Add("agentId", fmt.Sprintf("%v", agentId))
//	//v.Add("gameId", gameId)
//	////TODO:
//	////v.Add("records", records)
//	//v.Add("amount", fmt.Sprintf("%v", amount))
//	//v.Add("note", note)
//	//err = post(host+"/chips/creates?"+v.Encode(), nil)
//	//return
//
//	command:=&ChipsCreatesCommand{
//		AgentId:agentId,
//		GameId:gameId,
//		Records:records,
//	}
//
//	err = postJsonNew(host+"/chips/creates",command,nil)
//	if err != nil {
//		return
//	}
//
//	return
//}

/**
消费点控金币

字段	字段名	类型	必填	备注
userId	用户id	int64	是
agentId	业主编号	int	是
gameId	游戏Id	string	是	游戏分配的id
amount	码量	int64	是

返回参数
字段	字段名	类型	描述
amount	剩于数量	int	-1 结束点控，> 0 每次剩余点控量
*/
//func ConsumePoint(userId int64, agentId int, gameId string, amount int64) (resultAmount int64, err error) {
//	//v := url.Values{}
//	//v.Add("userId", fmt.Sprintf("%v", userId))
//	//v.Add("agentId", fmt.Sprintf("%v", agentId))
//	//v.Add("gameId", gameId)
//	//v.Add("amount", fmt.Sprintf("%v", amount))
//	//err = post(host+"/chips/creates?"+v.Encode(), nil)
//	//return
//
//	command:=&UserConsumePointCommand{
//		UserId:userId,
//		AgentId:agentId,
//		GameId:gameId,
//		Amount:amount,
//	}
//
//	err = postJsonNew(host+"/user/consumePoint",command,resultAmount)
//	if err != nil {
//		return
//	}
//
//	return
//}

/**
游戏推送信息

字段	字段名	类型	必填	备注
Header	头信息	map[string]string	是	序列化方式 {"Content-Type":"application/json"}
Body	数据内容	bytes	是	{"wsId":"","data":""}序列化的bytes
-wsId	wsId	string	是
-wsIds	wsId列表	[]string	否	批量时使用
-data	数据	string	是	需要上送的数据

*/
//func PushNotify() {
//
//}

/**
获取通用机器人
字段	字段名	类型	必填	备注
roomId	房间类型	string	是
gameId	游戏Id	string	是
num	数量	int64	是	最大获取数量为20个

返回参数:
command	指令策略	int	是	0:不干预 1:正向干预 2:反向干预
list	机器人列表信息	 []UserInfo	是	用户对象信息
  invoked in gameapi & roomserver
*/
func GetAIRobots(roomId, gameId string, num int64, agentId int32, result interface{}) (err error) {
	//v := url.Values{}
	//v.Add("roomId", roomId)
	//v.Add("gameId", gameId)
	//v.Add("num", strconv.Itoa(num))
	//err = post(host+"/robot/getAIRobots?"+v.Encode(), result)
	//return

	command := &RobotGetAIRobotsCommand{
		RoomId: roomId,
		GameId: gameId,
		Num:    num,
	}
	fmt.Printf("=================== GetAIRobots: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err = postJsonNew(host+"/robot/getAIRobots", command, result, agentId)
	if err != nil {
		return
	}

	return
}

/**
释放机器人

字段	字段名	类型	必填	备注
userIds	用户id	[]int64	是

返回参数
无
 invoked in roomserver
*/
func ReleaseAIRobots(userIds []int64, agentId int32) (err error) {

	command := &RobotReleaseRobotsCommand{
		UserIds: userIds,
	}
	fmt.Printf("=================== ReleaseAIRobots: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err = postJsonNewNoRV(host+"/robot/ReleaseRobots", command, agentId)
	if err != nil {
		return
	}

	return
}

/**
获取镜像机器人

字段	字段名	类型	必填	备注
roomId	房间类型	string	是
gameId	游戏Id	string	是
userIds	用户IDS	[]int64	是

返回参数
字段	字段名	类型	必填	备注
mirrorUserMap	机器人用户与镜象用户	map<int64,int64>	是	key为机器人ID，value为镜象用户ID
list	机器人列表信息	 []UserInfo
是	用户对象信息

*/
func GetMirrorRobots(roomId string, gameId string, userIds []int64, result interface{}) (err error) {
	return
}

///**
//注册服务
//*/
//func RegistGameStatus(serverId string) {
//	//var host = fmt.Sprintf("game-%v", serverId)
//}

type PostResultOfRoomConfigs struct {
	Code    int    `json:"code"`    //200:成功 详见【状态码】
	Message string `json:"message"` //接口描述信息
	//Data    interface{} `json:"data"`    //请求json数据
	Data *GameRoomConfigInfoResult `json:"data"` //请求json数据
}

type PostResultOfUserInfo struct {
	Code    int    `json:"code"`    //200:成功 详见【状态码】
	Message string `json:"message"` //接口描述信息
	//Data    interface{} `json:"data"`    //请求json数据
	Data *UserInfo `json:"data"` //请求json数据
}

//type PostUserBalance struct {
//	Code    int    `json:"code"`    //200:成功 详见【状态码】
//	Message string `json:"message"` //接口描述信息
//	//Data    interface{} `json:"data"`    //请求json数据
//	Data    *AccountGetBalanceInfo `json:"data"`    //请求json数据
//}

/**
获得房间配置
 invoked in roomserver
*/
func GameSearchRoomConfigs(gameId string, val interface{}) (err error) {
	//v := url.Values{}
	//
	//v.Add("gameId", strconv.FormatInt(gameId,10))
	//err = post(host+"/game/searchRoomConfigs?"+v.Encode(), result)

	//return

	command := &GameSearchRoomConfigsCommand{
		GameId: gameId,
	}
	fmt.Printf("=================== GameSearchRoomConfigs: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err = postJsonNew(host+"/game/searchRoomConfigs", command, val, 0)
	if err != nil {
		return
	}

	return
}

/**GameGetBloodCurrentLevelInfo
获取房间机器人配置
*/
func GameSearchRoomRobotConfigs(gameId string, val interface{}, agentId int32) (err error) {
	//v := url.Values{}
	//
	//v.Add("gameId", strconv.FormatInt(gameId,10))
	//err = post(host+"/game/searchRoomRobotConfigs?"+v.Encode(), result)
	//
	//return

	command := &GameSearchRoomConfigsCommand{
		GameId: gameId,
	}

	err = postJsonNew(host+"/game/searchRoomRobotConfigs", command, val, agentId)
	if err != nil {
		return
	}

	return
}

//房间机器人配置变动
//func GameRoomRobotState(gameId int64,agentId int64,roomId string,isOpenAiRobot,isOpenMirrorRobot bool)(err error){
//	//v := url.Values{}
//	//
//	//v.Add("gameId", strconv.FormatInt(gameId,10))
//	//v.Add("agentId", strconv.FormatInt(gameId,10))
//	//v.Add("roomId", roomId)
//	//v.Add("isOpenAiRobot", strconv.FormatBool(isOpenAiRobot))
//	//v.Add("isOpenMirrorRobot", strconv.FormatBool(isOpenMirrorRobot))
//	//
//	//err = post(host+"/game/roomRobotState?"+v.Encode(), result)
//	//
//	//return
//
//	command:=&GameRoomRobotStateCommand{
//		GameId:gameId,
//		AgentId:agentId,
//		RoomId:roomId,
//		IsOpenAiRobot:isOpenAiRobot,
//		IsOpenMirrorRobot:isOpenMirrorRobot,
//	}
//
//	err = postJsonNew(host+"/game/roomRobotState",command,nil)
//	if err != nil {
//		return
//	}
//
//	return
//}

//获取当前彩金
func GameGetCurrentLottery(gameId, roomId string, result interface{}, agentId int32) (actualDeduction int64, err error) {

	//v := url.Values{}
	//v.Add("gameId", gameId)
	//v.Add("roomId", roomId)
	//err = post(host+"/game/getCurrentLottery?"+v.Encode(), result)
	//
	//return

	command := &GameGetCurrentLotteryCommand{
		GameId:  gameId,
		RoomId:  roomId,
		AgentId: agentId,
	}

	err = postJsonNew(host+"/game/getCurrentLottery", command, actualDeduction, agentId)
	if err != nil {
		return
	}

	return
}

//消耗彩金
func GameDelLottery(gameId, roomId string, userId int64, matchId string, delRate int64, agentId int32) (actualDeduction int64, err error) {
	//v := url.Values{}
	//v.Add("gameId", gameId)
	//v.Add("roomId", roomId)
	//v.Add("userId", strconv.FormatInt(userId,10))
	//v.Add("roomId", matchId)
	//v.Add("delRate", strconv.FormatInt(delRate,10))
	//err = post(host+"/game/delLottery?"+v.Encode(), result)
	//
	//return

	command := &GameDelLotteryCommand{
		GameId:  gameId,
		RoomId:  roomId,
		UserId:  userId,
		MatchId: matchId,
		DelRate: delRate,
	}

	err = postJsonNew(host+"/game/delLottery", command, actualDeduction, agentId)
	if err != nil {
		return
	}

	return
}

//获取血池  invoked in gameapi
//func GameGetBloodCurrentLevel(gameId,roomId string, agentId int32)(currentLevel int64,err error){
func GameGetBloodCurrentLevel(gameId, roomId string, agentId int32) (currentLevel int64, err error) {
	//v := url.Values{}
	//v.Add("gameId", gameId)
	//v.Add("roomId", roomId)
	//err = post(host+"/game/getBloodCurrentLevel?"+v.Encode(), result)
	//
	//return

	command := &GameGetBloodCurrentLevelCommand{
		GameId:  gameId,
		RoomId:  roomId,
		AgentId: agentId,
	}
	fmt.Printf("=================== GameGetBloodCurrentLevel: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	result := &GameGetBloodCurrentLevelInfo{}

	err = postJsonNew(host+"/game/getBloodCurrentLevel", command, result, agentId)
	if err != nil {
		return
	}

	currentLevel = result.CurrentLevel

	return
}

//获取用户点控  invoked in gameapi
func GameSearchUserPoints(userIds []int64, gameId, roomId string, agentId int32) (result *UserSearchUserPointsInfoResult, err error) {

	command := &UserSearchUserPointsCommand{
		UserIds: userIds,
		GameId:  gameId,
		RoomId:  roomId,
	}
	fmt.Printf("=================== GameSearchUserPoints: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	result = &UserSearchUserPointsInfoResult{}

	err = postJsonNew(host+"/user/searchUserPoints", command, result, agentId)
	if err != nil {
		return
	}

	return
}

// 游戏战绩推送接口   invoked in gameapi
func GameResultPush(gameId, matchId, roomId string, userId, profitAmout, drawAmount, betAmount, outputAmount int64, agentId int32) error {

	records := make([]GameResultRecordInfo, 0)
	rd := GameResultRecordInfo{
		UserId:       userId,
		BetAmount:    betAmount,
		ProfitAmount: profitAmout,
		DrawAmount:   drawAmount,
		OutputAmount: outputAmount,
	}

	records = append(records, rd)

	command := GameResultsCommand{
		GameId:  gameId,
		MatchId: matchId,
		RoomId:  roomId,
		Records: records,
	}

	fmt.Printf("=================== GameResultPush: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	err := postJsonNewNoRV(host+"/game/results", command, agentId)
	if err != nil {
		return err
	}

	return nil
}

// 更新余额
func UpdateBalance(userId int64, gameId string, tradeNo string, amount int64, agentId int32) error {

	command := UpdateBalanceCommand{
		UserId:  userId,
		GameId:  gameId,
		TradeNo: tradeNo,
		Amount:  amount,
	}

	err := postJsonNewNoRV(host+"/game/updateBalance", command, agentId)
	if err != nil {
		return err
	}

	return nil
}

//获得配牌  for local test
func GetAllocationCard(userIds []string, gameId string) (*GetAllocationCardRsp, error) {

	command := GetAllocationCardCommand{
		UserIds: userIds,
		GameId:  gameId,
	}
	fmt.Printf("=================== GetAllocationCard: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	rsp := &GetAllocationCardRsp{}

	err := postJsonNew(host+"/game/getGameCards", command, rsp, 0)
	if err != nil {
		return nil, err
	}

	return rsp, nil
}

//获得底牌
func GetBottomCard() (result *GetBottomCardCommandRsp, err error) {

	fmt.Printf("=================== GetBottomCard: %v\n", time.Now().Format(time.RFC3339Nano))

	result = &GetBottomCardCommandRsp{}

	err = postJsonNew(host+"/game/getXZDDLastCard", nil, result, 0)

	if err != nil {

		return result, err
	}

	return result, nil
}

//获得游戏条件
func GetGameCondition(gameId string) (*GetGameConditionRsp, error) {

	command := GetGameConditionCommand{
		GameId: gameId,
	}

	fmt.Printf("=================== GetGameCondition: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	rsp := &GetGameConditionRsp{}

	err := postJsonNew(host+"/game/getGameCondition", command, rsp, 0)
	if err != nil {
		return nil, err
	}

	return rsp, nil
}

//获得玩家控制
func GetUserControl(userId, gameId string) (*GetUserControlRsp, error) {

	command := GetUserControlCommand{
		UserId: userId,
		GameId: gameId,
	}

	fmt.Printf("=================== GetUserControl: %v | %v\n", command, time.Now().Format(time.RFC3339Nano))
	rsp := &GetUserControlRsp{}

	err := postJsonNew(host+"/game/getUserControl", command, rsp, 0)
	if err != nil {
		return nil, err
	}

	return rsp, nil
}
